﻿using System;
using System.Collections;
using System.Collections.Generic;
using Assist;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;

namespace YJKRevitCurveDrag
{
	public class TestJigControler
	{
		public TestJigControler(ExternalCommandData commandData)
		{
			this.m_Revit = commandData;
			this.m_Options = this.m_Revit.Application.Application.Create.NewGeometryOptions();
			this.m_Options.View = this.m_Revit.Application.ActiveUIDocument.Document.ActiveView;
		}

		public bool Test(ref string message)
		{
			List<JigEdgeInfo> curveInfos = new List<JigEdgeInfo>();
			if (!this.GetElementCurveInfo(ref curveInfos))
			{
				return false;
			}
			XYZ ptBase = null;
			if (!this.GetBasePoint(ref ptBase))
			{
				return false;
			}
			XYZ ptInsert = null;
			List<JigTextInfo> textInfos = new List<JigTextInfo>();
			if (!DragCurveJigInterface.GetInsertPosition(this.m_Revit, curveInfos, false, textInfos, false, ptBase, ref ptInsert))
			{
				return false;
			}
			this.NewMark(ptInsert);
			return true;
		}

		private bool GetElementCurveInfo(ref List<JigEdgeInfo> curveInfos)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			IList<Reference> list = null;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				list = selection.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, "select elements");
			}
			catch (Exception)
			{
				return false;
			}
			foreach (Reference reference in list)
			{
				Element element = document.GetElement(reference);
				if (element.GetType() == typeof(FamilyInstance))
				{
					this.GetFamilyInstanceCurveInfo(element as FamilyInstance, ref curveInfos);
				}
				else
				{
					this.GetOtherElementCurveInfo(element, ref curveInfos);
				}
			}
			return true;
		}

		private void GetFamilyInstanceCurveInfo(FamilyInstance element, ref List<JigEdgeInfo> curveInfos)
		{
			GeometryElement geometryElement = element.GetOriginalGeometry(this.m_Options);
			geometryElement = geometryElement.GetTransformed(element.GetTransform());
			if (null == geometryElement)
			{
				return;
			}
			IEnumerator<GeometryObject> enumerator = geometryElement.GetEnumerator();
			List<GeometryObject> geometryObjectArray = RevitVersionFuncs.GetGeometryObjectArray(geometryElement);
			while (enumerator.MoveNext())
			{
				GeometryObject item = enumerator.Current;
				geometryObjectArray.Add(item);
			}
			new List<XYZ>();
			foreach (GeometryObject obj in geometryObjectArray)
			{
				this.GetCurveInfoFromGeometryObject(obj, ref curveInfos);
			}
		}

		private void GetOtherElementCurveInfo(Element element, ref List<JigEdgeInfo> curveInfos)
		{
			GeometryElement geometryElement = element.get_Geometry(this.m_Options);
			if (null == geometryElement)
			{
				return;
			}
			IEnumerator<GeometryObject> enumerator = geometryElement.GetEnumerator();
			List<GeometryObject> geometryObjectArray = RevitVersionFuncs.GetGeometryObjectArray(geometryElement);
			while (enumerator.MoveNext())
			{
				GeometryObject item = enumerator.Current;
				geometryObjectArray.Add(item);
			}
			new List<XYZ>();
			foreach (GeometryObject obj in geometryObjectArray)
			{
				this.GetCurveInfoFromGeometryObject(obj, ref curveInfos);
			}
		}

		private void GetCurveInfoFromGeometryObject(GeometryObject obj, ref List<JigEdgeInfo> curveInfos)
		{
			if (obj.GetType() == typeof(Solid))
			{
				IEnumerator enumerator = (obj as Solid).Edges.GetEnumerator();
				{
					while (enumerator.MoveNext())
					{
						object obj2 = enumerator.Current;
						JigEdgeInfo jigEdgeInfo = new JigEdgeInfo(((Edge)obj2).AsCurve());
						if (!jigEdgeInfo.IsNull())
						{
							curveInfos.Add(jigEdgeInfo);
						}
					}
					return;
				}
			}
			if (obj.GetType() == typeof(Arc))
			{
				JigEdgeInfo jigEdgeInfo2 = new JigEdgeInfo(obj as Arc);
				if (jigEdgeInfo2.IsNull())
				{
					return;
				}
				curveInfos.Add(jigEdgeInfo2);
				return;
			}
			else if (obj.GetType() == typeof(Line))
			{
				JigEdgeInfo jigEdgeInfo3 = new JigEdgeInfo(obj as Line);
				if (jigEdgeInfo3.IsNull())
				{
					return;
				}
				curveInfos.Add(jigEdgeInfo3);
			}
		}

		private bool GetCurveInfo(ref List<JigEdgeInfo> curveInfos)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			IList<Reference> list = null;
			Selection selection = this.m_Revit.Application.ActiveUIDocument.Selection;
			try
			{
				list = selection.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, new CurveFilter(), "select curves");
			}
			catch (Exception)
			{
				return false;
			}
			foreach (Reference reference in list)
			{
				Element element = document.GetElement(reference);
				if (element.GetType() == typeof(ModelLine))
				{
					JigEdgeInfo item = new JigEdgeInfo((element as ModelLine).GeometryCurve as Line);
					curveInfos.Add(item);
				}
				else if (element.GetType() == typeof(ModelArc))
				{
					JigEdgeInfo item2 = new JigEdgeInfo((element as ModelArc).GeometryCurve as Arc);
					curveInfos.Add(item2);
				}
				else if (element.GetType() == typeof(DetailLine))
				{
					JigEdgeInfo item3 = new JigEdgeInfo((element as DetailLine).GeometryCurve as Line);
					curveInfos.Add(item3);
				}
				else if (element.GetType() == typeof(DetailArc))
				{
					JigEdgeInfo item4 = new JigEdgeInfo((element as DetailArc).GeometryCurve as Arc);
					curveInfos.Add(item4);
				}
			}
			return true;
		}

		private bool GetBasePoint(ref XYZ ptBase)
		{
			XYZ xyz = null;
			try
			{
				xyz = this.m_Revit.Application.ActiveUIDocument.Selection.PickPoint("please pick point on column");
			}
			catch (Exception)
			{
				return false;
			}
			ptBase = new XYZ(xyz.X, xyz.Y, 0.0);
			return true;
		}

		private void NewMark(XYZ ptInsert)
		{
			Document document = this.m_Revit.Application.ActiveUIDocument.Document;
			Transaction transaction = new Transaction(document);
			transaction.Start("create mark");
			CurveArray curveArray = new CurveArray();
			double num = 3.0;
			XYZ xyz = new XYZ(ptInsert.X - num, ptInsert.Y + num, 0.0);
			XYZ xyz2 = new XYZ(ptInsert.X + num, ptInsert.Y - num, 0.0);
			Line line = Line.CreateBound(xyz, xyz2);
			curveArray.Append(line);
			XYZ xyz3 = new XYZ(ptInsert.X - num, ptInsert.Y - num, 0.0);
			xyz2 = new XYZ(ptInsert.X + num, ptInsert.Y + num, 0.0);
			Line line2 = Line.CreateBound(xyz3, xyz2);
			curveArray.Append(line2);
			XYZ origin = new XYZ(0.0, 0.0, 0.0);
			Plane plane = RevitVersionFuncs.CreatePlanByNormalAndOrigin(new XYZ(0.0, 0.0, 1.0), origin);
			SketchPlane sketchPlane = RevitVersionFuncs.NewSketchPlane(document, plane);
			document.Create.NewModelCurveArray(curveArray, sketchPlane);
			transaction.Commit();
		}

		private ExternalCommandData m_Revit;

		private Options m_Options;
	}
}
